/*
 *   Licensed to the Apache Software Foundation (ASF) under one
 *   or more contributor license agreements.  See the NOTICE file
 *   distributed with this work for additional information
 *   regarding copyright ownership.  The ASF licenses this file
 *   to you under the Apache License, Version 2.0 (the
 *   "License"); you may not use this file except in compliance
 *   with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing,
 *   software distributed under the License is distributed on an
 *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *   KIND, either express or implied.  See the License for the
 *   specific language governing permissions and limitations
 *   under the License.
 *
 */

package org.apache.directory.server.codec.json.operations.bind;


import java.lang.reflect.Type;

import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
import org.apache.directory.shared.ldap.message.BindRequestImpl;
import org.apache.directory.shared.ldap.name.DN;
import org.apache.directory.shared.ldap.util.Base64;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;


/**
 * TODO BindRequestDecoder.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class BindRequestCodec implements JsonSerializer<BindRequestImpl>, JsonDeserializer<BindRequestImpl>
{

    private static final String SIMPLE = "simple";
    private static final String MECHANISM = "mechanism";
    private static final String VERSION3 = "version3";
    private static final String CREDENTIALS = "credentials";
    private static final String NAME = "name";


    public JsonElement serialize( BindRequestImpl src, Type typeOfSrc, JsonSerializationContext context )
    {
        JsonObject jsonObj = new JsonObject();

        jsonObj.addProperty( NAME, src.getName().getName() );
        jsonObj.addProperty( CREDENTIALS, String.valueOf( Base64.encode( src.getCredentials() ) ) );
        jsonObj.addProperty( VERSION3, src.getVersion3() );
        jsonObj.addProperty( MECHANISM, src.getSaslMechanism() );
        jsonObj.addProperty( SIMPLE, src.isSimple() );

        return jsonObj;
    }


    public BindRequestImpl deserialize( JsonElement element, Type typeOfT, JsonDeserializationContext context )
        throws JsonParseException
    {
        try
        {
            JsonObject jsonObj = element.getAsJsonObject();

            BindRequestImpl bindReq = new BindRequestImpl();
            bindReq.setName( new DN( jsonObj.get( NAME ).getAsString() ) );

            String pwd = jsonObj.get( CREDENTIALS ).getAsString();
            bindReq.setCredentials( Base64.decode( pwd.toCharArray() ) );

            JsonElement version = jsonObj.get( VERSION3 );
            if ( version != null )
            {
                bindReq.setVersion3( version.getAsBoolean() );
            }

            JsonElement mechanism = jsonObj.get( MECHANISM );
            if ( mechanism != null )
            {
                bindReq.setSaslMechanism( mechanism.getAsString() );
            }

            JsonElement simple = jsonObj.get( SIMPLE );
            if ( simple != null )
            {
                bindReq.setSimple( simple.getAsBoolean() );
            }

            return bindReq;
        }
        catch ( LdapInvalidDnException e )
        {
            throw new JsonParseException( e );
        }
    }

}
